package org.colcon.web.model;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.colcon.web.model.framework.IPower;
import org.colcon.web.model.framework.ITitle;
import org.colcon.web.model.framework.IUser;
import org.colcon.web.model.title.MemberTitle;

public class Title extends Law implements ITitle
{
	private static final long serialVersionUID = 5495690195691831364L;
	
	private static final String
	
		// containers
		POWERS = "powers";
	
	/** full paths to required titles */
	private Set<String> requiredTitles;
	
	/** full paths to holders of this title */
	private Set<String> holders;
	
	private int count;
	
	public Title()
	{
		this(new HashMap<String, String>());
	}
	
	public Title(Map<String, String> args)
	{
		this(args.get(PARENT), args.get(ID), args.get(TEXT));
	}
	
	public Title(String parent, String id, String text)
	{
		this(parent, id, text, -1, new String[0], new IPower[0]);
	}
	
	public Title(String parent, String id, String text, int count, String[] requiredTitles, IPower[] powers)
	{
		super(parent, id, text);
		
		addContainer(POWERS);
		
		this.requiredTitles = new HashSet<String>();
		
		if(requiredTitles != null)
			for(String path : getRequiredTitles())
				this.requiredTitles.add(path);
		
		if(powers != null)
			for(IPower p : powers)
				addPower(p);
	
		holders = new HashSet<String>();
		
		this.count = count;
	}
	
	public String getLongName()
	{
		return getId() + " of " + getGroup();
	}
	
	public String[] getRequiredTitles()
	{
		return requiredTitles.toArray(new String[0]);
	}
	
	public String[] getHolders()
	{
		return holders.toArray(new String[0]);
	}
	
	public IPower[] getPowers()
	{
		return getGrandChildren(POWERS).toArray(new IPower[0]);
	}
	
	public boolean hasHolder(String id)
	{
		return holders.contains(id);
	}
	
	public boolean addHolder(String id)
	{
		if(!open())
			return false;
		
		return holders.add(id);
	}
	
	public boolean removeHolder(String id)
	{
		return holders.remove(id);
	}
	
	public IPower getPower(String id)
	{
		return (IPower) get(POWERS, id);
	}
	
	public boolean hasPower(String id)
	{
		return getPower(id) != null;
	}
	
	public boolean addPower(IPower power)
	{
		return add(POWERS, power);
	}
	
	public boolean removePower(String id)
	{
		return remove(POWERS, id);
	}
	
	public boolean isMemberTitle()
	{
		return this instanceof MemberTitle;
	}
	
	public boolean isEligible(IUser user)
	{
		for(String title : requiredTitles)
			if(!user.hasTitle(title))
				return false;
		
		return true;
	}
	
	public boolean open()
	{
		return count < 0 || holders.size() < count;
	}
}
